package com.uuticketweb.ticket.flight.action;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.uuticket.processor.Processor;
import com.uuticket.processor.ProcessorFactory;
import com.uuticketweb.ticket.flight.service.FlightService;
import com.uuticketweb.ticket.flight.service.OrderService;
import com.uuticketweb.ticket.flight.service.factory.FlightServiceFactory;
import com.uuticketweb.ticket.flight.service.factory.OrderServiceFactory;
import com.uuticketweb.ticket.pojos.Order;
import com.uuticketweb.ticket.pojos.OrderContact;
import com.uuticketweb.ticket.pojos.Passenger;
import com.uuticketweb.ticket.pojos.SimpleOrder;
import com.uuticketweb.ticket.pojos.TwoCode;
import com.uuticketweb.ticket.util.DateHelper;


@SuppressWarnings("serial")
public class OrderAction extends ActionSupport{
	
	private static final Log logger = LogFactory.getLog(OrderAction.class);
	
	public String selfOrder() throws Exception {
		Map para = ActionContext.getContext().getParameters();
		
		Map<String, String> map = new HashMap<String, String>();
		String company = ((String[])para.get("company"))[0];
		map.put("company", company);
		Object toAirport01 = para.get(company + "_to_departure_0");
		if(toAirport01 != null) {
			String toAirport02 = ((String[])para.get(company + "_to_dest_0"))[0];
			Object turnAirport = para.get(company + "_to_departure_1");
			if(turnAirport != null) {
				String toAirport11 = ((String[])turnAirport)[0];
				String toAirport12 = ((String[])para.get(company + "_to_dest_1"))[0];
				map.put("departure", ((String[])toAirport01)[0]);
				map.put("dest", toAirport12);
				map.put("turncity", toAirport02);
			} else {
				map.put("departure", ((String[])toAirport01)[0]);
				map.put("dest", toAirport02);
			}
		} else {
			// if the to planeinfo is empty, use the back itinary to get the depart and dest
			toAirport01 = para.get(company + "_back_departure_0");
			String toAirport02 = ((String[])para.get(company + "_back_dest_0"))[0];
			Object turnAirport = para.get(company + "_back_dest_1");
			if(turnAirport != null) {
				String toAirport11 = ((String[])turnAirport)[0];
				String toAirport12 = ((String[])para.get(company + "_back_dest_1"))[0];
				map.put("departure", ((String[])toAirport01)[0]);
				map.put("dest", toAirport11);
				map.put("turncity", toAirport02);
			} else {
				map.put("departure", ((String[])toAirport01)[0]);
				map.put("dest", toAirport02);
			}
		}
		
		Object toOffDate = para.get(company + "_to_offdate_0");
		if(toOffDate != null) {
			map.put("toOffDate", ((String[])toOffDate)[0]);
		}
		Object toDownDate = para.get(company + "_to_downdate_0");
		if(toDownDate != null) {
			map.put("toDownDate", ((String[])toDownDate)[0]);
		}
		
		Object backOffDate = para.get(company + "_back_offdate_0");
		if(backOffDate != null) {
			map.put("backOffDate", ((String[])backOffDate)[0]);
		}
		Object backDownDate = para.get(company + "_back_downdate_0");
		if(backDownDate != null) {
			map.put("backDownDate", ((String[])backDownDate)[0]);
		}
		
		Object toTransferDate = para.get(company + "_to_transferdate_0");
		if(toTransferDate != null) {
			map.put("toTransferDate", ((String[])toTransferDate)[0]);
		}
		Object backTransferDate = para.get(company + "_back_transferdate_0");
		if(backTransferDate != null) {
			map.put("backTransferDate", ((String[])backTransferDate)[0]);
		}
		
		Object toPlaneno = para.get(company + "_to_planeno_0");
		if(toPlaneno != null) {
			map.put("toPlaneno", ((String[])toPlaneno)[0]);
		}
		Object toTransferPlaneno = para.get(company + "_to_planeno_1");
		if(toTransferPlaneno != null) {
			map.put("toTransferPlaneno", ((String[])toTransferPlaneno)[0]);
		}
		Object backPlaneno = para.get(company + "_back_planeno_0");
		if(backPlaneno != null) {
			map.put("backPlaneno", ((String[])backPlaneno)[0]);
		}
		Object backTransferPlaneno = para.get(company + "_back_planeno_1");
		if(backTransferPlaneno != null) {
			map.put("backTransferPlaneno", ((String[])backTransferPlaneno)[0]);
		}
		
		String price = ((String[])para.get(company + "_price"))[0];
		String tax = ((String[])para.get(company + "_tax"))[0];
		map.put("price", price);
		map.put("tax", tax);
		
		String strPNo = ((String[])para.get("passengersNum"))[0];
		int pNo = Integer.parseInt(strPNo);
		map.put("passengersNum", strPNo);
		ActionContext.getContext().put("passengersNum", pNo);
		
		ActionContext.getContext().put("flightDetailMap", map);
		return "selfOrder";
	}
	
	public String createSelfOrder() throws Exception {
		Map para = ActionContext.getContext().getParameters();
		
		// order contact
		String contactName = ((String[])para.get("contactName"))[0];
		String contactTel = ((String[])para.get("contactTel"))[0];
		String contactMsn = ((String[])para.get("contactMsn"))[0];
		
		Order order = new Order();
		OrderContact orderContact = new OrderContact();
		orderContact.setName(contactName);
		orderContact.setTel(contactTel);
		orderContact.setMsn(contactMsn);
		
		// passengers
		List passengerList = new ArrayList();
		int i = 1;
		while(i > 0) {
			Object obj = para.get("firstname_" + i);
			if(obj == null) break;
			
			String firstname = ((String[])obj)[0];
			if("".equals(firstname.trim())) continue;
			
			String lastname = ((String[])para.get("lastname_" + i))[0];
			String title = ((String[])para.get("title_" + i))[0];
			String sex = ((String[])para.get("sex_" + i))[0];
			String idType = ((String[])para.get("idType_" + i))[0];
			String idCode = ((String[])para.get("idCode_" + i))[0];
			String validityTime = ((String[])para.get("validityTime_" + i))[0];
			Date dateValid = DateHelper.parseDate(validityTime);
			String nationality = ((String[])para.get("nationality_" + i))[0];
			String strBirthday = ((String[])para.get("birthday_" + i))[0];
			Date birthday = null;
			if(strBirthday != null) {
				birthday = DateHelper.parseDate(strBirthday);
			}
			
			Passenger passenger = new Passenger("", nationality, firstname, lastname, title, sex, birthday, idType, idCode, dateValid, "", "", "");
			passenger.setOrder(order);
			passengerList.add(passenger);
			
			i ++;
		}
		
		order.setPassengerList(passengerList);
		
		String departure = ((String[])para.get("departure"))[0];
		String dest = ((String[])para.get("dest"))[0];
		Object obj = para.get("turncity");
		String turncity = (obj == null ? null : ((String[])obj)[0]);
		
		obj = para.get("toOffDate");
		Date toOffDate = obj == null ? null : DateHelper.parseDate(((String[])obj)[0]);
		obj = para.get("toDownDate");
		Date toDownDate = obj == null ? null : DateHelper.parseDate(((String[])obj)[0]);
		
		obj = para.get("backOffDate");
		Date backOffDate = (obj == null ? null : DateHelper.parseDate(((String[])obj)[0]));
		obj = para.get("backDownDate");
		Date backDownDate = (obj == null ? null : DateHelper.parseDate(((String[])obj)[0]));
		
		obj = para.get("toTransferDate");
		Date toTransferDate = (obj == null ? null : DateHelper.parseDate(((String[])obj)[0]));
		obj = para.get("backTransferDate");
		Date backTransferDate = (obj == null ? null : DateHelper.parseDate(((String[])obj)[0]));
		
		obj = para.get("toPlaneno");
		String toPlaneno = (obj == null ? null : ((String[])obj)[0]);
		obj = para.get("toTransferPlaneno");
		String toTransferPlaneno = (obj == null ? null : ((String[])obj)[0]);
		obj = para.get("backPlaneno");
		String backPlaneno = (obj == null ? null : ((String[])obj)[0]);
		obj = para.get("backTransferPlaneno");
		String backTransferPlaneno = (obj == null ? null : ((String[])obj)[0]);
		
		float price = Float.parseFloat(((String[])para.get("price"))[0]);
		float tax = Float.parseFloat(((String[])para.get("tax"))[0]);
		
		String company = ((String[])para.get("company"))[0];
		
		FlightService flightService = FlightServiceFactory.getFlightService();
		TwoCode airlineCompany = flightService.getCompanyFromTwocode(company);
		order.setAirlineCompany(airlineCompany);
		
		order.setOffAirport(flightService.getAirportByThreeCode(departure));
		order.setDownAirport(flightService.getAirportByThreeCode(dest));
		if(turncity != null) {
			order.setTransferAirport(flightService.getAirportByThreeCode(turncity));
		}
		order.setGoOffDate(toOffDate);
		order.setGoDownDate(toDownDate);
		order.setBackOffDate(backOffDate);
		order.setBackDownDate(backDownDate);
		order.setGoTransferDate(toTransferDate);
		order.setBackTransferDate(backTransferDate);
		order.setToPlaneno(toPlaneno);
		order.setToTransferPlaneno(toTransferPlaneno);
		order.setBackPlaneno(backPlaneno);
		order.setBackTransferPlaneno(backTransferPlaneno);
		order.setPrice(price);
		order.setTax(tax);
		
		OrderService orderService = OrderServiceFactory.getOrderService();
		orderService.saveOrderContact(orderContact);
		order.setOrderContact(orderContact);
		order.setCreatedDate(new Date());
		orderService.saveOrder(order);
		order.setOrderno(createOrderNo(order.getId(), "Z"));
		
		// excutePNR
		Map<String, String> inputMap = new HashMap<String, String>();
		String planePair = "";
		if(!StringUtils.isBlank(toPlaneno)) {
			planePair += toPlaneno;
			if(!StringUtils.isBlank(toTransferPlaneno)) {
				planePair += "-" + toTransferPlaneno;
			}
		}
		if(!StringUtils.isBlank(backPlaneno)) {
			if(planePair.length() > 0) {
				if(planePair.indexOf("-") != -1) {
					planePair += "," + backPlaneno + "-" + backTransferPlaneno;
				} else {
					planePair += "-" + backPlaneno;
				}
			} else {
				planePair += backPlaneno;
				if(!StringUtils.isBlank(backTransferPlaneno)) {
					planePair += "-" + backTransferPlaneno;
				}
			}
		}
		inputMap.put("planePair", planePair);
		
		String cityPair = "";
		if(!StringUtils.isBlank(toPlaneno)) {
			cityPair += order.getOffAirport().getAirportThreeCode();
			if(turncity == null) {
				cityPair += order.getDownAirport().getAirportThreeCode();
			} else {
				cityPair += order.getTransferAirport().getAirportThreeCode() + "," + order.getTransferAirport().getAirportThreeCode() + order.getDownAirport().getAirportThreeCode();
			}
		}
		if(!StringUtils.isBlank(backPlaneno)) {
			if(cityPair.length() > 0) cityPair += ",";
			cityPair += order.getDownAirport().getAirportThreeCode();
			if(turncity == null) {
				cityPair += order.getOffAirport().getAirportThreeCode();
			} else {
				cityPair += order.getTransferAirport().getAirportThreeCode() + "," + order.getTransferAirport().getAirportThreeCode() + order.getOffAirport().getAirportThreeCode();
			}
		}
		inputMap.put("cityPair", cityPair);
		
		String date = "";
		if(toOffDate != null) {
			date += DateHelper.toCMDDate(toOffDate);
			if(toTransferDate != null) {
				date += "," + DateHelper.toCMDDate(toTransferDate);
			}
			date += "," + DateHelper.toCMDDate(toDownDate);
		}
		if(backOffDate != null) {
			if(date.length() > 0) {
				date += ",";
			}
			date += backOffDate;
			if(backTransferDate != null) {
				date += "," + DateHelper.toCMDDate(backTransferDate);
			}
			date += "," + DateHelper.toCMDDate(backDownDate);
		}
		inputMap.put("date", date);
		
		String passengers = "";
		for(i = 0; i < passengerList.size(); i ++) {
			Passenger passenger = (Passenger)passengerList.get(i);
			if(passenger != null) {
				if(passengers.length() != 0) {
					passengers += ",";
				}
				passengers += passenger.getTitle() + "_" + passenger.getLastName() + "/" + passenger.getFirstName();
			}
		}
		inputMap.put("passengers", passengers);
		
		debugQteMap(inputMap);
		Map<String, String> re = excutePNR(inputMap, company);
		if(re.get("pnr") != null) {
			order.setAdultPnr(re.get("pnr"));
		}
		orderService.updatePojo(order);
		return "success";
	}
	
	private Map<String, String> excutePNR(Map<String, String> inputMap, String carrier) {
		//inputMap.put("pnr", "CS12SD");
		
		Processor p = ProcessorFactory.getProcessor(carrier);
		return p.excutePNR(inputMap);
	}

	private void debugQteMap(Map<String, String> map) {
		Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
		while(iter.hasNext()) {
			Entry<String, String> entry = iter.next();
			String name = entry.getKey();
			String value = entry.getValue();
			logger.debug(name + " : " + value);
		}
	}
	
	public String simpleOrder() throws Exception {
		return "simpleOrder";
	}
	
	public String createSimpleOrder() throws Exception {
		Map para = ActionContext.getContext().getParameters();
		
		// order contact
		String contactName = ((String[])para.get("contactName"))[0];
		String contactTel = ((String[])para.get("contactTel"))[0];
		String contactMsn = ((String[])para.get("contactMsn"))[0];
		
		OrderContact orderContact = new OrderContact();
		orderContact.setName(contactName);
		orderContact.setTel(contactTel);
		orderContact.setMsn(contactMsn);
		
		SimpleOrder order = new SimpleOrder();
		
		// passengers
		/*
		List passengerList = new ArrayList();
		int i = 1;
		while(i > 0) {
			Object obj = para.get("name_" + i);
			if(obj == null) break;
			
			String name = ((String[])obj)[0];
			if("".equals(name.trim())) continue;
			
			String sex = ((String[])para.get("sex_" + i))[0];
			String idType = ((String[])para.get("idType_" + i))[0];
			String idCode = ((String[])para.get("idCode_" + i))[0];
			String validityTime = ((String[])para.get("validityTime_" + i))[0];
			Date dateValid = DateHelper.parseDate(validityTime);
			String nationality = ((String[])para.get("nationality_" + i))[0];
			String strBirthday = ((String[])para.get("birthday_" + i))[0];
			Date birthday = null;
			if(strBirthday != null) {
				birthday = DateHelper.parseDate(strBirthday);
			}
			
			Passenger passenger = new Passenger("", nationality, name, sex, birthday, idType, idCode, dateValid, "", "", "");
			passenger.setSimpleOrder(order);
			passengerList.add(passenger);
			
			i ++;
		}
		
		order.setPassengerList(passengerList);
		*/
		OrderService orderService = OrderServiceFactory.getOrderService();
		order.setTripDetail(((String[])para.get("tripDetail"))[0]);
		order.setFlightType(((String[])para.get("flightType"))[0]);
		order.setPassengersInfo(((String[])para.get("passengersInfo"))[0]);
		order.setTotalPassengers(Integer.parseInt(((String[])para.get("totalPassengerN"))[0]));
		order.setYBunkNum(Integer.parseInt(((String[])para.get("YBunkNum"))[0]));
		order.setFBunkNum(Integer.parseInt(((String[])para.get("FBunkNum"))[0]));
		order.setCBunkNum(Integer.parseInt(((String[])para.get("CBunkNum"))[0]));
		order.setCanChangeDepartDate(((String[])para.get("canChangeDepartDate"))[0]);
		order.setCanChangeCity(((String[])para.get("canChangeCity"))[0]);
		order.setCreatedDate(new Date());
		orderService.saveOrderContact(orderContact);
		order.setOrderContact(orderContact);
		orderService.saveSimpleOrder(order);
		order.setOrderno(createOrderNo(order.getId(), "S"));
		orderService.updatePojo(order);
		return "success";
		
	}
	
	private String createOrderNo(long id, String prefix) {
		int minLength = 6;
		String strid = String.valueOf(id);
		strid = StringUtils.leftPad(strid, minLength, "0");
		return prefix + strid;
	}
	
	public String searchOrder() throws Exception {
		Map para = ActionContext.getContext().getParameters();
		String strCreatedDate = (para.get("createdDate") == null ? null : ((String[])para.get("createdDate"))[0]);
		Date createdDate = null;
		if(!StringUtils.isBlank(strCreatedDate)) {
			try {
				createdDate = DateHelper.parseDate(strCreatedDate);
			} catch (ParseException e) {
			}
		}
		
		String orderNo = (para.get("orderno") == null ? null : ((String[])para.get("orderno"))[0]);
		if(!StringUtils.isBlank(orderNo)) {
			orderNo = orderNo.trim().toUpperCase();
		}
		
		String tripKeyword = (para.get("tripkeyword") == null ? null : ((String[])para.get("tripkeyword"))[0]);
		if(!StringUtils.isBlank(tripKeyword)) {
			tripKeyword = tripKeyword.trim();
		}
		
		String guestKeyword = (para.get("guestKeyword") == null ? null : ((String[])para.get("guestKeyword"))[0]);
		if(!StringUtils.isBlank(guestKeyword)) {
			guestKeyword = guestKeyword.trim();
		}
		
		OrderService orderService = OrderServiceFactory.getOrderService();
		List orderList = orderService.searchOrder(tripKeyword, guestKeyword, orderNo, createdDate);
		ActionContext.getContext().put("orderList", orderList);
		return "searchOrder";
	}
	
	public String searchSimpleOrder() throws Exception {
		Map para = ActionContext.getContext().getParameters();
		String strCreatedDate = (para.get("createdDate") == null ? null : ((String[])para.get("createdDate"))[0]);
		Date createdDate = null;
		if(!StringUtils.isBlank(strCreatedDate)) {
			try {
				createdDate = DateHelper.parseDate(strCreatedDate);
			} catch (ParseException e) {
			}
		}
		
		String orderNo = (para.get("orderno") == null ? null : ((String[])para.get("orderno"))[0]);
		if(!StringUtils.isBlank(orderNo)) {
			orderNo = orderNo.trim().toUpperCase();
		}
		
		String tripKeyword = (para.get("tripkeyword") == null ? null : ((String[])para.get("tripkeyword"))[0]);
		if(!StringUtils.isBlank(tripKeyword)) {
			tripKeyword = tripKeyword.trim();
		}
		
		OrderService orderService = OrderServiceFactory.getOrderService();
		List orderList = orderService.searchSimpleOrder(orderNo, tripKeyword, createdDate);
		ActionContext.getContext().put("orderList", orderList);
		return "searchSimpleOrder";
	}
	
	public String orderDetail() throws Exception {
		String strId = null;
		if(ActionContext.getContext().getParameters().get("orderId") != null) {
			strId = ((String[])ActionContext.getContext().getParameters().get("orderId"))[0];
		}
		Order order = null;
		if(strId != null) {
			order = getOrderFromId(strId);
		}
		if(order != null) {
			ActionContext.getContext().put("order", order);
		}
		return "orderDetail";
	}
	
	public String simpleOrderDetail() throws Exception {
		String strId = null;
		if(ActionContext.getContext().getParameters().get("orderId") != null) {
			strId = ((String[])ActionContext.getContext().getParameters().get("orderId"))[0];
		}
		SimpleOrder order = null;
		if(strId != null) {
			order = getSimpleOrderFromId(strId);
		}
		if(order != null) {
			ActionContext.getContext().put("order", order);
		}
		return "simpleOrderDetail";
	}

	public Order getOrderFromId(String id) throws Exception {
		return (Order)OrderServiceFactory.getOrderService().getPojo(Long.parseLong(id), Order.class);
	}
	
	public SimpleOrder getSimpleOrderFromId(String id) throws Exception {
		return (SimpleOrder)OrderServiceFactory.getOrderService().getPojo(Long.parseLong(id), SimpleOrder.class);
	}
}
